package com.disk.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.disk.entity.constants.Constants;
import com.disk.entity.dto.SessionWebUserDto;
import com.disk.entity.dto.UserSpaceDto;
import com.disk.entity.po.FileInfo;
import com.disk.entity.po.UserInfo;
import com.disk.mapper.FileInfoMapper;
import com.disk.mapper.UserInfoMapper;
import com.disk.service.EmailCodeService;
import com.disk.service.UserInfoService;
import com.disk.utils.RedisComponent;
import com.disk.utils.RedisOperationUtils;
import com.disk.utils.StringTools;
import com.mysql.cj.util.StringUtils;
import io.netty.util.internal.StringUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户信息 服务实现类
 * </p>
 *
 * @author zsy
 * @since 2024-08-06
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Resource
    private UserInfoMapper userInfoMapper;

    @Resource
    private EmailCodeService emailCodeService;

    @Resource
    private RedisComponent redisComponent;

    @Resource
    private FileInfoMapper fileInfoMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void register(String email, String nickname, String password, String emailCode) {
        UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getEmail, email));
        if (userInfo != null) {
            throw new RuntimeException("邮箱已被注册");
        }

        //校验邮箱验证码
        emailCodeService.checkCode(email, emailCode);

        userInfo = new UserInfo();
        //生成唯一用户id
        String userId = StringTools.getRandomNumber(10);
        while (userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserId, userId)) != null) {
            userId = StringTools.getRandomNumber(10);
        }
        userInfo.setUserId(userId);
        userInfo.setEmail(email);
        userInfo.setNickName(nickname);
        userInfo.setPassword(StringTools.encodeByMd5(password));
        userInfo.setStatus(1);
        userInfo.setUseSpace(0L);
        //初始化用户空间
        userInfo.setTotalSpace(Constants.MB * 1000);
        userInfoMapper.insert(userInfo);
    }

    @Override
    public SessionWebUserDto login(String email, String password) {

        UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getEmail, email));
        if (userInfo == null) {
            throw new RuntimeException("邮箱不存在");
        } else if (!userInfo.getPassword().equals(password)) {
            throw new RuntimeException("账号或者密码错误");
        } else if (userInfo.getStatus() == 0) {
            throw new RuntimeException("账号已被禁用");
        }
        userInfo.setLastLoginTime(LocalDateTime.now());
        userInfoMapper.updateById(userInfo);
        SessionWebUserDto sessionWebUserDto = new SessionWebUserDto();
        sessionWebUserDto.setUserId(userInfo.getUserId());
        sessionWebUserDto.setNickName(userInfo.getNickName());
        sessionWebUserDto.setAvatar(userInfo.getQqAvatar());
        //TODO 是否为管理员
        sessionWebUserDto.setAdmin(false);
        UserSpaceDto userSpaceDto = new UserSpaceDto();

        // 获取用户已上传文件的占用空间
        List<Long> fileSizes = fileInfoMapper.selectList(new LambdaQueryWrapper<FileInfo>()
                        .eq(FileInfo::getUserId, userInfo.getUserId())
                        .select(FileInfo::getFileSize))
                .stream()
                .filter(Objects::nonNull)
                .map(FileInfo::getFileSize)
                .collect(Collectors.toList());
        Long useSpace = fileSizes.stream().mapToLong(Long::longValue).sum();


        userSpaceDto.setUseSpace(useSpace);
        userSpaceDto.setTotalSpace(userInfo.getTotalSpace());
        redisComponent.saveUserSpaceUse(userInfo.getUserId(), userSpaceDto);
        return sessionWebUserDto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetPwd(String email, String password, String emailCode) {
        UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getEmail, email));
        if (userInfo == null) {
            throw new RuntimeException("邮箱不存在");
        }
        emailCodeService.checkCode(email, emailCode);
        userInfo.setPassword(StringTools.encodeByMd5(password));
        userInfoMapper.insert(userInfo);
    }
}
